using System.Collections;
using System.Collections.Generic;
using FrameWork.AStar;
using UnityEngine;
using UnityEngine.Tilemaps;

namespace FrameWork.TileMapManager
{
    public class AStarAndGetTilesData : SingletonMonoBehaviour<AStarAndGetTilesData>
    {
        public Tilemap tilemap; // 将Tilemap拖到这个字段上

        private int minXValue;
        private int minYValue;

        private AStartManager aStartManager;

        protected override void Awake()
        {
            base.Awake();

            aStartManager = new AStartManager();
        }

        private void Start()
        {
            // 获取所有瓦片位置
            BoundsInt bounds = tilemap.cellBounds;
            List<Vector3Int> tilePositions = new List<Vector3Int>();

            foreach (Vector3Int position in bounds.allPositionsWithin)
            {
                if (tilemap.HasTile(position))
                {
                    tilePositions.Add(position);
                }
            }

            // 确定数组的大小和偏移量
            int minX = int.MaxValue;
            int maxX = int.MinValue;
            int minY = int.MaxValue;
            int maxY = int.MinValue;

            foreach (Vector3Int position in tilePositions)
            {
                if (position.x < minX) minX = position.x;
                if (position.x > maxX) maxX = position.x;
                if (position.y < minY) minY = position.y;
                if (position.y > maxY) maxY = position.y;
            }
            
            minXValue = minX;
            minYValue = minY;

            int width = maxX - minX + 1;
            int height = maxY - minY + 1;
            
            // 初始化 AStar 地图数组大小
            aStartManager.InitMapSizeInfo(width, height);
            
            // 保存 AStar 地图的瓦片信息
            foreach (Vector3Int position in tilePositions)
            {
                int arrayX = position.x - minX;
                int arrayY = position.y - minY;

                if (tilemap.GetTile(position).name == "Stop")
                {
                    aStartManager.InitMapInfo(arrayX, arrayY,999f, AStar_Node_Type.Stop);
                }
                else
                {
                    if (tilemap.GetTile(position).name == "Walk")
                    {
                        aStartManager.InitMapInfo(arrayX, arrayY, 1f, AStar_Node_Type.Walk);
                    }
                    else if (tilemap.GetTile(position).name == "Grass")
                    {
                        aStartManager.InitMapInfo(arrayX, arrayY, 5f, AStar_Node_Type.Walk);
                    }
                    else if (tilemap.GetTile(position).name == "Water")
                    {
                        aStartManager.InitMapInfo(arrayX, arrayY, 10f, AStar_Node_Type.Walk);
                    }
                }
            }

            // 测试 保存 AStar 地图的瓦片信息
            // foreach (var position in aStartManager.GetNodes)
            // {
            //     print("这个瓦片的位置是" + (position.x, position.y) + "这个瓦片的类型" + position.type); 
            // }
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="start">起点</param>
        /// <param name="end">终点</param>
        /// <returns></returns>
        public Queue<Vector3> AStarFindPath(Vector3 start, Vector3 end)
        {
            // 存放路径的队列
            Queue<Vector3> path = new Queue<Vector3>();
            
            // 转换为 TileMap 使用的 Vector3Int 坐标
            Vector3Int startPosition = tilemap.WorldToCell(start);
            Vector3Int endPosition = tilemap.WorldToCell(end);
            
            // 开始寻路，返回node节点，节点的 xy 为TileMap地图的 xy
            // 计算偏移位置，确保数组内寻找正确
            List<AStarNode> nodes = aStartManager.FindPath(new Vector2(startPosition.x - minXValue, startPosition.y - minYValue), new Vector2(endPosition.x - minXValue, endPosition.y-minYValue));
            
            // 如果节点集合为空，返回空值
            if (nodes == null)
                return null;
            
            // 如果不为空，寻路成功，将 TileMap 地图坐标转换为世界坐标添加到路径集合，最后返回该路径集合
            foreach (var VARIABLE in nodes)
            {
                path.Enqueue(tilemap.CellToWorld(tilemap.WorldToCell(new Vector3(VARIABLE.x + minXValue, VARIABLE.y + minYValue, 0))));
            }

            return path;
        }
    }
}
